#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("inline")
#include <iostream>
#include <unordered_map>
#include <map>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <set>
#include <ctime>
using namespace std;

struct Server{
    int id;  // 服务器编号
    string type;  // 服务器型号
    int cpu;  // 总的cpu
    int mem;  // 总的内存
    int cpu_A, cpu_B;  // A B 节点cpu剩余量
    int mem_A, mem_B;  // A B 节点内存剩余量
    int hardware_cost;  // 硬件花费
    int day_cost;  // 每日能耗花费
    unordered_map<int, int> vms_id;  // 存放部署在该服务器上的虚拟机id
};

struct VM{
    int id;  // 虚拟机ID
    string type;  // 虚拟机型号
    int cpu;
    int mem;
    bool isTwoNodes;  // 是否双节点部署
    int serverID;  // 该虚拟机所部署服务器的ID
    int assign_node;  // 该虚拟机安装在服务器的A节点则为1，B节点则为2
    string s; // 记录每个虚拟机的答案
};


class VmManager{
public:
    int num;  // 当前存活的虚拟机数目
    unordered_map<string, VM> type2VM;  // 建立类型到虚拟机的索引
    unordered_map<int, VM> ID2VM;  // 建立ID到虚拟机的索引
    int getMigrationNum();  // 获取可以的迁移次数
};

int VmManager::getMigrationNum() {
    int cnt = num / 200;
    return cnt;
}


struct Query{
    string type;  // 请求类型：add 或 del
    string vm_type;  // 创建时虚拟机类型
    int vm_id;  // 虚拟机ID
};

vector<vector<Query>> query;  // 处理每天的请求

class ServerManager{
public:
    vector<Server> servers;  // 存放所有的服务器
    vector<Server> ID2Server;  // 建立ID到服务器的索引
    unordered_map<string, Server> type2Server;  // 建立类型到服务器的索引
    unordered_map<string, int> num;  // 存放当前每种类型的服务器数目
    set<string> serverHash;  // 存放当前买了哪些类型的
    int serverID = -1;  // 建立服务器ID，每次新增服务器则此ID加1
    bool isEmpty(Server &server);  // 查看当前服务器是否为空
    long long getEnergyCost();  // 计算当前开机的服务器一天的能耗
    long long getHardwareCost();  // 计算当前买服务器的花费
    vector<double> getLoadRatio(Server &server);  // 获取当前服务器的负载率
};

// 方法申明区
vector<Query> reorderQuery(vector<Query> &vector);
bool query_cmp(const Query &q1, const Query &q2);

bool tryAssign(VM &vm);

bool tryAssignForMigration(VM &vm);

bool canAssign(Server &server, VM &vm, int node);

int getFitness(Server &server, VM &vm, int node);

int getFitness2(Server &server, VM &vm, int node);

void doAssign(Server &server, VM &vm, int node);

void undoAssign(Server &server, VM &vm, int node);

string chooseBestServer(vector<Query> temp, int processed);

void delVm(VM &vm);

Server chooseOne(vector<Server> vector);
string chooseBestServer2(VM &vm);

vector<string> migration();

vector<string> migration1();

double loadRatio();

ServerManager serverManager;
VmManager vmManager;

void read_data()
{
    int tot_cpu = 0, tot_mem = 0;
    // 读取服务器数据
    int N; cin >> N;

    for(int i = 0; i < N; i ++ ){
        Server server;
        string type; cin >> type;
        type = type.substr(1), type.pop_back();  // 去除行首括号和多余的逗号
        server.type = type;

        string cpu; cin >> cpu;
        cpu.pop_back();
        server.cpu = stoi(cpu);
        server.cpu_A = server.cpu / 2;
        server.cpu_B = server.cpu / 2;

        string mem; cin >> mem;
        mem.pop_back();
        server.mem = stoi(mem);
        server.mem_A = server.mem / 2;
        server.mem_B = server.mem / 2;

        string cost; cin >> cost;
        cost.pop_back();
        server.hardware_cost = stoi(cost);

        cin >> cost;
        cost.pop_back();
        server.day_cost = stoi(cost);
        server.vms_id.clear();
        serverManager.type2Server[server.type] = server;
        serverManager.servers.push_back(server);
    }

    // 读取虚拟机数据
    int M; cin >> M;
    for(int i = 0; i < M; i ++ ){
        VM vm;
        string type; cin >> type;
        type = type.substr(1), type.pop_back();
        vm.type = type;

        string cpu; cin >> cpu;
        cpu.pop_back();
        vm.cpu = stoi(cpu);

        string mem; cin >> mem;
        mem.pop_back();
        vm.mem = stoi(mem);

        string flag; cin >> flag;
        flag.pop_back();
        vm.isTwoNodes = stoi(flag);
        if(vm.isTwoNodes){
            vm.cpu /= 2;
            vm.mem /= 2;
        }
        vm.serverID = -2;
        vmManager.type2VM[vm.type] = vm;
    }

    // 处理请求数据
    int T; cin >> T;
    for(int i = 1; i <= T; i ++ ){
        vector<Query> dayQuery;  // 存放一天的请求
        int R; cin >> R;
        for(int j = 0; j < R; j ++ ){
            Query q;
            string type; cin >> type;
            type = type.substr(1), type.pop_back();
            q.type = type;

            if(q.type == "add"){
                string vm_type; cin >> vm_type;
                vm_type.pop_back();
                q.vm_type = vm_type;
            }

            string id; cin >> id;
            id.pop_back();
            q.vm_id = stoi(id);
            if(q.type == "add"){
                VM &vm = vmManager.type2VM[q.vm_type];
                tot_cpu += vm.cpu;
                tot_mem += vm.mem;
                vm.id = q.vm_id;
                vmManager.ID2VM[q.vm_id] = vm;
            }
            dayQuery.push_back(q);
        }
        query.push_back(dayQuery);
    }
}

double cntf = 0.0;
int main() {
    clock_t begin = clock();
    ios::sync_with_stdio(false);
//    freopen("../training-1.txt", "r", stdin);
    long long hardware_cost = 0, day_cost = 0;
    // 读取数据
    read_data();
    // 处理每天的请求
    int processedNum = 0;
    for(auto &dayQuery: query) {
        day_cost += serverManager.getEnergyCost();
        // 处理迁移
        vector<string> mig;
//        if(choose == 1) mig = migration1();
//        if(choose == 2) mig = migration();
        mig = migration();
        vector<Query> temp = reorderQuery(dayQuery);  // 重新排序今天的请求
        // 针对于当天的请求，选出最合适的一种类型的服务器类型
        string serverType = "";
        // 存放当天请求的答案
        vector<string> res;
        int last = serverManager.serverID;
        for(auto &q: temp){
            VM &vm = vmManager.ID2VM[q.vm_id];
            if(q.type == "add"){
                vmManager.num ++ ;
                // 从现在已有的服务器中看能否部署此虚拟机，如果能则挑一个最适合的服务器来部署
                bool f = tryAssign(vm);
                // 如果不能部署，则新买一个服务器部署
                if(!f){
                    // 从若干种服务器类型中选出一种来部署
                    serverManager.serverID ++ ;
//                    if(choose == 1){
//                        if(serverType == ""){  // 一天只会执行一次服务器选择操作
//                            serverType = chooseBestServer(temp, processedNum);
//                        }
//                    }
//                    else if(choose == 2) serverType = chooseBestServer2(vm);
                    serverType = chooseBestServer2(vm);
                    serverManager.serverHash.insert(serverType);
                    // 要购买的服务器
                    Server server = serverManager.type2Server[serverType];
                    server.id = serverManager.serverID;
                    if(vm.isTwoNodes) doAssign(server, vm, 0);
                    else doAssign(server, vm, 1);  // 单节点部署默认放在A节点
                    serverManager.ID2Server.push_back(server);
                    serverManager.num[serverType] ++ ;
                }
            }else if(q.type == "del"){
                vmManager.num -- ;
                delVm(vm);  // 删除此虚拟机
            }
            processedNum ++ ;
        }
        map<string, vector<Server>> mp;  // 记录每种服务器及其数目
        for(int id = last + 1; id <= serverManager.serverID; id ++ ){
            Server &server = serverManager.ID2Server[id];
            mp[server.type].push_back(server);
        }
        serverManager.serverID = last;
        for(auto &it: mp){
            for(auto &server: it.second){
                serverManager.serverID ++ ;
                int id = serverManager.serverID;
                server.id = id;
                for(auto &vm_id: server.vms_id){
                    VM &vm = vmManager.ID2VM[vm_id.first];
                    vm.serverID = id;
                }
                serverManager.ID2Server[id] = server;
            }
        }
        cout << "(purchase, " << mp.size() << ")" << endl;
        for(auto &it: mp) cout << "(" << it.first << ", " << it.second.size() << ")" << endl;
        cout << "(migration, " << mig.size() << ")" << endl;
        for(string &s: mig) cout << s << endl;
        for(auto &q: dayQuery){
            VM &vm = vmManager.ID2VM[q.vm_id];
            if(q.type == "add") {
                string s = to_string(vm.serverID);
                if(vm.assign_node == 1) s += ", A";
                if(vm.assign_node == 2) s += ", B";
                cout << "(" << s << ")" << endl;
            }
        }
    }
    hardware_cost += serverManager.getHardwareCost();
    day_cost += serverManager.getEnergyCost();
//    cout << "hardware_cost: " << hardware_cost << ", energy_cost: " << day_cost << endl;
//    cout << "total cost: " << hardware_cost + day_cost << endl;
//    clock_t end = clock();
//    cout << "cost time: " << end - begin << "ms" << endl;
    return 0;
}
bool cmp2(int a, int b){  // 按照占用cpu+mem小从小到大排序
    auto &t1 = serverManager.ID2Server[a], &t2 = serverManager.ID2Server[b];
//    if(t1.vms_id.size() != t2.vms_id.size()) return t1.vms_id.size() < t2.vms_id.size();
    return t1.cpu - t1.cpu_A - t1.cpu_B + t1.mem - t1.mem_A - t1.mem_B <
            t2.cpu - t2.cpu_A - t2.cpu_B + t2.mem - t2.mem_A - t2.mem_B;
}
double lisan(Server &server, VM &vm){
    // vm部署在server上的离散系数
    double x = 2.0 * vm.cpu / server.cpu;
    double y = 2.0 * vm.mem / server.mem;
    return max(x - y, y - x) / (x + y);
}
bool vm_cmp(const int a, const int b){
    VM &vm1 = vmManager.ID2VM[a], &vm2 = vmManager.ID2VM[b];
    if(vm1.isTwoNodes != vm2.isTwoNodes) return vm1.isTwoNodes < vm2.isTwoNodes;
//    Server &server = serverManager.ID2Server[vm1.serverID];
//    return lisan(server, vm1) > lisan(server, vm2);
    return vm1.cpu + vm1.mem < vm2.cpu + vm2.mem;
}

vector<string> migration1() {  // 每次迁移的虚拟机数目不超过当前存活虚拟机数目的千分之5
    vector<string> res;  // 存放每次转移的信息
    int sz = 5 * vmManager.ID2VM.size() / 1000;
    vector<int> temp;  // 从小到大存放拥有虚拟机数目的服务器ID
    for(int i = 0; i <= serverManager.serverID; i ++ ) temp.push_back(i);
    sort(temp.begin(), temp.end(), cmp2);
    while(temp.size() >= 200) temp.pop_back();
    for(int a: temp){  // 尝试将ID为a的服务器上的虚拟机转移到其他服务器上去
        unordered_map<int, int> vms_id = serverManager.ID2Server[a].vms_id;
        vector<int> vms;
        for(auto &it: vms_id) vms.push_back(it.first);
        if(vms_id.size() > sz) break;
        for(int b = 0; b <= serverManager.serverID; b ++ ){  // 尝试将a上虚拟机转移到b上去
            if(b == a) continue;
            Server &server = serverManager.ID2Server[b];
            if(serverManager.isEmpty(server)) continue;
            auto &t = serverManager.ID2Server[a];  // a 服务器
            if(t.cpu / 2 - t.cpu_A <= server.cpu_A && t.cpu / 2 - t.cpu_B <= server.cpu_B
               && t.mem / 2 - t.mem_A <= server.mem_A && t.mem / 2 - t.mem_B <= server.mem_B){
                // 当前a服务器使用的cpu和mem不超过b服务器剩余的，可以将a种虚拟机转移到b中
                for(int vm_id: vms){
                    VM &vm = vmManager.ID2VM[vm_id];
                    vm.serverID = b;
                    if(vm.isTwoNodes) {
                        server.cpu_A -= vm.cpu, server.mem_A -= vm.mem;
                        server.cpu_B -= vm.cpu, server.mem_B -= vm.mem;
                        res.push_back("(" + to_string(vm_id) + ", " + to_string(b) + ")");
                    }else{
                        if(vm.assign_node == 1){
                            server.cpu_A -= vm.cpu, server.mem_A -= vm.mem;
                            res.push_back("(" + to_string(vm_id) + ", " + to_string(b) + ", " + "A)");
                        }else{
                            server.cpu_B -= vm.cpu, server.mem_B -= vm.mem;
                            res.push_back("(" + to_string(vm_id) + ", " + to_string(b) + ", " + "B)");
                        }
                    }
                    server.vms_id[vm_id] = 1;
                }
                t.vms_id.clear();
                t.cpu_A = t.cpu_B = t.cpu / 2;
                t.mem_A = t.mem_B = t.mem / 2;
                sz -= vms_id.size();
                break;
            }
        }
    }
    return res;
}

vector<string> migration() {
    // 获取当前服务器负载率
//    double f = loadRatio();
    vector<string> res;  // 存放每次转移的信息
//    if(f < 0.08) return res;
    int sz = vmManager.getMigrationNum();  // 可迁移次数
    vector<int> temp;  // 从小到大存放拥有虚拟机数目的服务器ID
    for(int i = 0; i <= serverManager.serverID; i ++ ) temp.push_back(i);
    sort(temp.begin(), temp.end(), cmp2);
    for(int i = 0; i < temp.size(); i ++ ){
        int id = temp[i];
        auto &server = serverManager.ID2Server[id];
        vector<int> vmsId;
        for(auto &vmId: server.vms_id){
            vmsId.push_back(vmId.first);
        }
        sort(vmsId.begin(), vmsId.end(), vm_cmp);
        for(int vmId: vmsId){
            VM &vm = vmManager.ID2VM[vmId];
            int a = vm.serverID, b = vm.assign_node;
            if(sz <= 0) return res;
            undoAssign(server, vm, b);
            bool f = tryAssignForMigration(vm); //
            if(f){
                if(a == vm.serverID && b == vm.assign_node) continue;  // 未迁移
                string s = to_string(vm.id) + ", " + to_string(vm.serverID);
                if(vm.assign_node == 1) s += ", A";
                if(vm.assign_node == 2) s += ", B";
                res.push_back("(" + s + ")");
//                undoAssign(server, vm, b);
                sz -- ;
            }else{
                doAssign(server, vm, b);
            }
        }
    }
    return res;
}

double loadRatio() {
    double ret = 0.0;
    for(int i = 0; i <= serverManager.serverID; i ++ ){
        auto &server = serverManager.ID2Server[i];
        double cpu = 1.0 * (server.cpu_A + server.cpu_B) / server.cpu;
        double mem = 1.0 * (server.mem_A + server.mem_B) / server.mem;
        ret += (cpu + mem) / 2.0;
    }
    ret /= serverManager.serverID;
    return ret;
}

void delVm(VM &vm) {
    Server &server = serverManager.ID2Server[vm.serverID];
    server.vms_id.erase(vm.id);
    if(vm.isTwoNodes){
        server.cpu_A += vm.cpu, server.mem_A += vm.mem;
        server.cpu_B += vm.cpu, server.mem_B += vm.mem;
    }else{
        if(vm.assign_node == 1){
            server.cpu_A += vm.cpu, server.mem_A += vm.mem;
        }else{
            server.cpu_B += vm.cpu, server.mem_B += vm.mem;
        }
    }
}

string chooseBestServer(vector<Query> dayQuery, int processed) {
    int cpu = 0, mem = 0;
    int cnt = 2 * dayQuery.size() / 3;
    for(auto &q: dayQuery){
        cnt -- ;
        VM &vm = vmManager.type2VM[q.vm_type];
        if(cnt < 0) {
            cpu += vm.cpu, mem += vm.mem;
            if(vm.isTwoNodes)
                cpu += vm.cpu, mem += vm.mem;
        }
    }
    double f1 = 1.0 * cpu / mem;
    map<double, Server> sortedServer;  // 按照差距从小到大排序
    for(auto &server: serverManager.servers){
        double f2 = 1.0 * server.cpu / server.mem;
        double d = f1 - f2;
        if(d < 0) d = -d;
        sortedServer[d] = server;
    }
    Server ret;
    vector<Server> temp;  // 挑选四个最接近的服务器
    for(auto &it: sortedServer){
        Server &server = it.second;
        bool can = true;  // 判断该服务器能否装下所有虚拟机
        for(auto &q: dayQuery){
            VM &vm = vmManager.type2VM[q.vm_type];
            if(server.cpu_A < vm.cpu || server.mem_A < vm.mem){
                can = false;
                break;
            }
        }
        if(can){
            temp.push_back(server);
        }
        if(temp.size() >= 4){
            break;
        }
    }
    // 选择性价比最高的一款
    ret = chooseOne(temp);
    return ret.type;
}
bool cmp(const Server &s1, const Server &s2){  // 性价比比较
    double f1 = s1.hardware_cost / s1.cpu + s1.hardware_cost / s1.mem + 100 * (s1.day_cost / s1.cpu + s1.day_cost / s1.mem);
    double f2 = s2.hardware_cost / s2.cpu + s2.hardware_cost / s2.mem + 100 * (s2.day_cost / s2.cpu + s2.day_cost / s2.mem);
    return s1.hardware_cost < s2.hardware_cost;
}
string chooseBestServer2(VM &vm) {
    vector<Server> temp;
    for(auto server: serverManager.servers){
        if(server.cpu_A <= vm.cpu + 3 || server.mem_A <= vm.mem + 3) continue;
        temp.push_back(server);
    }

    if(temp.size() == 0){
        for(auto server: serverManager.servers){
            if(server.cpu_A < vm.cpu || server.mem_A < vm.mem) continue;
            temp.push_back(server);
        }
    }
    sort(temp.begin(), temp.end(), cmp);
    return temp[0].type;
}
Server chooseOne(vector<Server> temp) {
    sort(temp.begin(), temp.end(), cmp);
    return temp[0];
}
bool tryAssignForMigration(VM &vm) {
    // 存放能部署此虚拟机的服务器的信息，每个数组是{服务器id, 虚拟机部署在哪个节点(0:all, 1:A, 2: B)，服务器与该虚拟机的匹配度}
//    vector<vector<int>> temp;
    int resFitness = INT32_MIN, resID = -1, resNode = -1;
    for(int id = 0; id <= serverManager.serverID; id ++ ){
        Server &server = serverManager.ID2Server[id];
        if(vm.isTwoNodes) {
            if (canAssign(server, vm, 0)) {  // 判断当前服务器cpu和内存能部署此虚拟机
                int fitness = getFitness(server, vm, 0);
//                if(server.id == serverID && delnode == 0) continue;
                if(fitness > resFitness){
                    resFitness = fitness;
                    resID = id;
                    resNode = 0;
                }
//                temp.push_back(vector<int>{id, 0, fitness});
            }
        }else{
            if(canAssign(server, vm, 1)){
                int fitness = getFitness(server, vm, 1);
                if(fitness > resFitness){
                    resFitness = fitness;
                    resID = id;
                    resNode = 1;
                }
//                temp.push_back(vector<int>{id, 1, fitness});
            }else if(canAssign(server, vm, 2)){
                int fitness = getFitness(server, vm, 2);
                if(fitness > resFitness){
                    resFitness = fitness;
                    resID = id;
                    resNode = 2;
                }
//                temp.push_back(vector<int>{id, 2, fitness});
            }
        }
    }

    // 如果没有一台服务器能部署此虚拟机则直接返回false
    if(resID == -1) return false;

//    // 挑选出最匹配的服务器部署此虚拟机
//    int d = temp[0][2], id = temp[0][0], node = temp[0][1];
//    for(auto &t: temp){
//        if(t[2] > d){
//            id = t[0];
//            node = t[1];
//            d = t[2];
//        }
//    }
    // 部署此虚拟机
    Server &server = serverManager.ID2Server[resID];
    doAssign(server, vm, resNode);
    return true;
}

bool tryAssign(VM &vm) {
    // 存放能部署此虚拟机的服务器的信息，每个数组是{服务器id, 虚拟机部署在哪个节点(0:all, 1:A, 2: B)，服务器与该虚拟机的匹配度}
    vector<vector<int>> temp;
    for(int id = 0; id <= serverManager.serverID; id ++ ){
        Server &server = serverManager.ID2Server[id];
        if(vm.isTwoNodes) {
            if (canAssign(server, vm, 0)) {  // 判断当前服务器cpu和内存能部署此虚拟机
                int fitness = getFitness(server, vm, 0);
                temp.push_back(vector<int>{id, 0, fitness});
            }
        }else{
            if(canAssign(server, vm, 1)){
                int fitness = getFitness(server, vm, 1);
                temp.push_back(vector<int>{id, 1, fitness});
            }else if(canAssign(server, vm, 2)){
                int fitness = getFitness(server, vm, 2);
                temp.push_back(vector<int>{id, 2, fitness});
            }
        }
    }

    // 如果没有一台服务器能部署此虚拟机则直接返回false
    if(temp.empty()) return false;

    // 挑选出最匹配的服务器部署此虚拟机
    int d = temp[0][2], id = temp[0][0], node = temp[0][1];
    for(auto &t: temp){
        if(t[2] > d){
            id = t[0];
            node = t[1];
            d = t[2];
        }
    }
    // 部署此虚拟机
    Server &server = serverManager.ID2Server[id];
    doAssign(server, vm, node);
    return true;
}

void doAssign(Server &server, VM &vm, int node) {
    server.vms_id[vm.id] = 1;
    vm.serverID = server.id;
    vm.assign_node = node;
    if(node == 0){
        server.cpu_A -= vm.cpu, server.mem_A -= vm.mem;
        server.cpu_B -= vm.cpu, server.mem_B -= vm.mem;
    }else if(node == 1){
        server.cpu_A -= vm.cpu, server.mem_A -= vm.mem;
    }else{
        server.cpu_B -= vm.cpu, server.mem_B -= vm.mem;
    }
}
void undoAssign(Server &server, VM &vm, int node) {
    server.vms_id.erase(vm.id);
    if(node == 0){
        server.cpu_A += vm.cpu, server.mem_A += vm.mem;
        server.cpu_B += vm.cpu, server.mem_B += vm.mem;
    }else if(node == 1){
        server.cpu_A += vm.cpu, server.mem_A += vm.mem;
    }else{
        server.cpu_B += vm.cpu, server.mem_B += vm.mem;
    }
}

inline int getFitness(Server &server, VM &vm, int node) {
    double d1 = (server.cpu_A - vm.cpu) + (server.mem_A - vm.mem);
    double d2 = (server.cpu_B - vm.cpu) + (server.mem_B - vm.mem);
    if(node == 0) return - d1 - d2;
    else if(node == 1) return - d1;
    else return - d2;
}

//int getFitness(Server &server, VM &vm, int node) {  // 按照加了之后负载率高低作为fitness
//    int factor = 50;
////    if(choose == 2) factor = 50;
//    if(serverManager.isEmpty(server)) return 0;
//    if(node == 0){
//        return min(factor * (server.cpu - server.cpu_A - server.cpu_B + 2 * vm.cpu) / server.cpu,
//                   factor * (server.mem - server.mem_A - server.mem_B + 2 * vm.mem) / server.mem);
//    }
//    else if(node == 1) return min(factor * (server.cpu / 2 - server.cpu_A + vm.cpu) / server.cpu,
//                                  factor * (server.mem / 2 - server.mem_A + vm.mem) / server.mem);
//    else if(node == 2) return min(factor * (server.cpu / 2 - server.cpu_B + vm.cpu) / server.cpu,
//                                  factor * (server.mem / 2 - server.mem_B + vm.mem) / server.mem);
//}
int getFitness2(Server &server, VM &vm, int node) {  // 按照加了之后离散系数高低作为fitness
    int factor = 50;
    double x0 = (2 * vm.cpu + server.cpu_A + server.cpu_B) / server.cpu;
    double y0 = (2 * vm.mem + server.mem_A + server.mem_B) / server.mem;
    if(node == 0){
        return factor * max(x0 - y0, y0 - x0) / (x0 + y0);
    }
    double x1 = 2 * (vm.cpu + server.cpu_A) / server.cpu;
    double y1 = 2 * (vm.mem + server.mem_A) / server.mem;
    if(node == 1) return factor * max(x1 - y1, y1 - x1) / (x1 + y1);
    double x2 = 2 * (vm.cpu + server.cpu_B) / server.cpu;
    double y2 = 2 * (vm.mem + server.mem_B) / server.mem;
    if(node == 2) return factor * max(x2 - y2, y2 - x2) / (x2 + y2);
}


bool canAssign(Server &server, VM &vm, int node) {
    if(node == 0){  // 能否双节点部署
        return server.cpu_A >= vm.cpu && server.mem_A >= vm.mem
               && server.cpu_B >= vm.cpu && server.mem_B >= vm.mem;
    }else if(node == 1){  // 能否部署在A节点
        return server.cpu_A >= vm.cpu && server.mem_A >= vm.mem;
    }else{  // 能否部署在B节点
        return server.cpu_B >= vm.cpu && server.mem_B >= vm.mem;
    }
}

vector<Query> reorderQuery(vector<Query> &dayQuery) {
    vector<vector<Query>> list;
    vector<Query> temp;
    for(auto &q: dayQuery){
        if(!temp.empty() && q.type != temp.back().type){
            list.push_back(temp);
            temp.clear();
        }
        temp.push_back(q);
    }
    if(!temp.empty()) list.push_back(temp);
    // 对list中每个部分重排序
    for(auto &item: list){
        if(item.back().type == "del") continue;
        sort(item.begin(), item.end(), query_cmp);
    }

    temp.clear();
    for(auto &item: list){
        for(auto &q: item){
            temp.push_back(q);
        }
    }
    return temp;
}
bool query_cmp(const Query &q1, const Query &q2){
    VM &v1 = vmManager.ID2VM[q1.vm_id], &v2 = vmManager.ID2VM[q2.vm_id];
    if(v1.isTwoNodes != v2.isTwoNodes) return v1.isTwoNodes > v2.isTwoNodes;
    int t1 = v1.cpu + v1.mem;
    int t2 = v2.cpu + v2.mem;
    return t1 > t2;
}
bool ServerManager::isEmpty(Server &server) {
    if(server.cpu_A + server.cpu_B == server.cpu && server.mem_A + server.mem_B == server.mem){
        return true;
    }
    return false;
}

long long ServerManager::getEnergyCost() {
    long long cost = 0;
    for(auto &it: ID2Server){
        auto &server = it;
        if(!isEmpty(server)) cost += server.day_cost;
    }
    return cost;
}

long long ServerManager::getHardwareCost() {
    long long cost = 0;
    for(auto &it: ID2Server){
        auto &server = it;
        cost += server.hardware_cost;
    }
    return cost;
}

vector<double> ServerManager::getLoadRatio(Server &server) {
    vector<double> ret(3, 0.0);  // ret[0]表示总的负载率，ret[1]表示A节点负载率，ret[2]表示B节点负载率
    return ret;
}
/*
 hardware_cost: 330319119, energy_cost: 177055349
total cost: 507374468

 hardware_cost: 367601611, energy_cost: 240135306
total cost: 607736917

 50
 hardware_cost: 328720727, energy_cost: 176571601
total cost: 505292328

hardware_cost: 367730359, energy_cost: 240287476
total cost: 608017835

  hardware_cost: 328720727, energy_cost: 176571601
total cost: 505292328

hardware_cost: 367730359, energy_cost: 240287476
total cost: 613841783
hardware_cost: 328720727, energy_cost: 176571601
total cost: 505292328

 hardware_cost: 321649695, energy_cost: 212715641
total cost: 534365336
 hardware_cost: 369525497, energy_cost: 241082186
total cost: 610607683

 serverID / 2, factor = 1000
 613687039 + 526736146 = 1140423185

 serverID / 2, factor = 50
 612569337 + 523812213 = 1136381550

 2 / 3 * serverID, factor = 50
 613827599 + 515853716 = 1129681315

 auto num, factor = 50
 617406922 + 508007862 = 1125414784

total cost: 508007862
cntf = 0.597969
 total cost: 617406922
cntf = 0.928715

 3 * f * serverID
total cost: 610515408
total cost: 508773381 = 1119288789


  2 * f * serverID
 total cost: 515413953
 total cost: 610965987

 4 * f * serverID
 total cost: 610462968
 total cost: 506583466 = 1117046434

 int sz = vmManager.getMigrationNum() * min(2 * f, 1.0);  // 可迁移次数
total cost: 612792312
 total cost: 505604563 = 1118396875

 int sz = vmManager.getMigrationNum() * min(3 * f, 1.0);
 612700365
 total cost: 509324779+612700365=1122025144

  int sz = vmManager.getMigrationNum() * min(1 * f, 1.0);
 total cost: 612128235 + 505653588 = 1117781823


 523028624 + 623034308
 517659661 + 627977352

610826568 + 507412478

int sz = vmManager.getMigrationNum() * min(3 * f, 1.0); // 老版本getFitness
 501695879 +612878804
 613037721 + 539582445  //
 637377942 + 512337766


 633345077+510484914=1143829991  migration
 597294729+491572142=1088866871
 613037721+539582445=1152620166

 hardware_cost: 365287862, energy_cost: 239492226
total cost: 604780088
 hardware_cost: 325622065, energy_cost: 170704163
total cost: 496326228

 hardware_cost: 366348949, energy_cost: 240500293
total cost: 606849242
 hardware_cost: 325205368, energy_cost: 171328567
total cost: 496533935


 hardware_cost: 364769388, energy_cost: 239262592
total cost: 604031980
 hardware_cost: 325112673, energy_cost: 170690077
total cost: 495802750

 hardware_cost: 360061098, energy_cost: 236983768
total cost: 597044866
 hardware_cost: 323648759, energy_cost: 168802684
total cost: 492451443
*/